package com.frogs.ucenter.v1.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.frogs.framework.util.PageList;
import com.frogs.framework.util.StringUtil;
import com.frogs.framework.util.date.DateUtil;
import com.frogs.system.util.BackStatusEnum;
import com.frogs.system.util.UserOrderLogShipmentStatusEnum;
import com.frogs.system.util.UserTypeEnum;
import com.frogs.system.web.api.request.Request;
import com.frogs.system.web.api.response.Response;
import com.frogs.system.web.api.response.Response.ApiResultEnum;
import com.frogs.system.web.exception.ServiceOperationException;
import com.frogs.ucenter.dao.UserLevelInfoDao;
import com.frogs.ucenter.dao.UserLevelOrderRecordDao;
import com.frogs.ucenter.dao.UserLevelUpgradeRegulationDao;
import com.frogs.ucenter.dao.UserOrderLogDao;
import com.frogs.ucenter.dao.UserOrderStatisticsDao;
import com.frogs.ucenter.entity.UserLevelInfo;
import com.frogs.ucenter.entity.UserLevelOrderRecord;
import com.frogs.ucenter.entity.UserLevelUpgradeRegulation;
import com.frogs.ucenter.entity.UserOrderLog;
import com.frogs.ucenter.entity.UserOrderStatistics;
import com.frogs.ucenter.v1.request.UserOrderAccumulatesRequest;
import com.frogs.ucenter.v1.request.UserOrderBackRequest;
import com.frogs.ucenter.v1.request.UserOrderLogAddRequest;
import com.frogs.ucenter.v1.request.UserOrderLogDelRequest;
import com.frogs.ucenter.v1.response.DefaultResponse;
import com.frogs.ucenter.v1.service.UserOrderService;
import com.frogs.ucenter.v1.util.ApiConstants;

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
@Service(ApiConstants.VERSION+"userOrderService")
public class UserOrderServiceImpl implements UserOrderService {
	
	private static final Logger log = LoggerFactory.getLogger(UserOrderServiceImpl.class);
	
	@Resource
	private UserOrderStatisticsDao userOrderStatisticsDao;
	@Resource
	private UserLevelOrderRecordDao userLevelOrderRecordDao;
	@Resource
	private UserLevelUpgradeRegulationDao userLevelUpgradeRegulationDao;
	@Resource
	private UserLevelInfoDao userLevelInfoDao;

	@Resource
	private UserOrderLogDao userOrderLogDao;
	
	private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

	@Override
	public Response deleteOrderLog(Request request) throws Exception {
		DefaultResponse response = new DefaultResponse();
		try {
			UserOrderLogDelRequest udr = (UserOrderLogDelRequest)request;
			Map<String,Object> params = new HashMap<String , Object>();
			params.put("eqUserId",udr.getUserId() );
			params.put("eqPartnerUserId",udr.getPartnerUserId() );
			params.put("eqPartnerOrderSn",udr.getPartnerOrderSn() );
			params.put("eqPartnerId",udr.getPartnerId() );
			if(!StringUtil.isEmpty(udr.getRemark())){
				params.put("remark",udr.getRemark() );
			}
			/*params.put("orderStatus",OrderDelStatusEnum.DEL_STATUS_YES.getId() );*/
			userOrderLogDao.updateByMap(params);
			response.setTip("删除成功");
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		
		
		return response;
	}

	@Override
	public Response updateOrderLog(Request request) throws Exception {
		DefaultResponse response = new DefaultResponse();
		try {
			UserOrderLogAddRequest udr = (UserOrderLogAddRequest)request;
			Map<String,Object> params = new HashMap<String , Object>();
			params.put("eqUserId",udr.getUserId() );
			params.put("eqPartnerUserId",udr.getPartnerUserId() );
			params.put("eqPartnerOrderSn",udr.getPartnerOrderSn() );
			params.put("eqPartnerId",udr.getPartnerId() );
			if(!StringUtil.isEmpty(udr.getRemark())){
				params.put("remark",udr.getRemark() );
			}
			if(!StringUtil.isEmpty(udr.getDetailJson())){
				params.put("detailJson",udr.getDetailJson() );
			}
			if(!StringUtil.isEmpty(udr.getMoney())){
				params.put("money",udr.getMoney() );
			}
			if(!StringUtil.isEmpty(udr.getPayStatus())){
				params.put("payStatus",udr.getPayStatus() );
			}
			if(!StringUtil.isEmpty(udr.getShipmentStatus())){
				params.put("shipmentStatus",udr.getShipmentStatus() );
			}
			if(!StringUtil.isEmpty(udr.getShippingAddress())){
				params.put("shippingAddress",udr.getShippingAddress() );
			}
			if(!StringUtil.isEmpty(udr.getShippingName())){
				params.put("shippingName",udr.getShippingName() );
			}
			if(!StringUtil.isEmpty(udr.getShippingPhone())){
				params.put("shippingPhone",udr.getShippingPhone() );
			}
			userOrderLogDao.updateByMap(params);
			response.setTip("修改成功");
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		
		
		return response;
	}

	@Override
	public Response insertOrderLog(Request request) throws Exception {
		DefaultResponse response = new DefaultResponse();
		try {
			UserOrderLogAddRequest udr = (UserOrderLogAddRequest)request;
			Map<String,Object> params = new HashMap<String , Object>();
			params.put("eqUserId",udr.getUserId() );
			params.put("eqPartnerUserId",udr.getPartnerUserId() );
			params.put("eqPartnerOrderSn",udr.getPartnerOrderSn() );
			params.put("eqPartnerId",udr.getPartnerId() );
			PageList<UserOrderLog> list = userOrderLogDao.selectByMap(params, false);
			if(list.size()==0){
				UserOrderLog ul = new UserOrderLog();
				ul.setCreateTime(new Date());
				ul.setDetailJson(udr.getDetailJson());
				ul.setMoney(udr.getMoney());
				/*ul.setOrderStatus(OrderDelStatusEnum.DEL_STATUS_NO.getId());*/
				ul.setOrderTime(format.parse(format.format(new Long(udr.getOrderTime()))));
				ul.setPartnerId(udr.getPartnerId());
				ul.setPartnerOrderSn(udr.getPartnerOrderSn());
				ul.setPartnerUserId(udr.getPartnerUserId());
				ul.setPayStatus(udr.getPayStatus());
				ul.setRemark(udr.getRemark());
				ul.setShipmentStatus(UserOrderLogShipmentStatusEnum.SHIPMENT_NO.getId());
				ul.setShippingAddress(udr.getShippingAddress());
				ul.setShippingName(udr.getShippingName());
				ul.setShippingPhone(udr.getShippingPhone());
				ul.setUserId(udr.getUserId());
				userOrderLogDao.insert(ul);
				response.setTip("添加成功");
			}else{
				response.setTip("添加失败,已有记录存在");
				response.setCode(ApiResultEnum.FAIL.getId());
			}
			
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		
		
		return response;
	}
	
	/**
	 * 累积用户金额、订单数，同时评估会员等级
	 * 
	 * 说明：
	 * 根据年份，有数据则修改累积数据，无数据则新增数据
	 * AOP异步查询升级规则，检查今年是否满足升级，检查是否绑定手机和邮箱
	 */
	@Override
	public Response accumulates(Request request) throws Exception {
		DefaultResponse response = new DefaultResponse();
		try {
			UserOrderAccumulatesRequest userOrderAccumulatesRequest = (UserOrderAccumulatesRequest) request;
			
			Map<String,Object> params = new HashMap<String , Object>();
			params.put("eqOrderYear",DateUtil.getYear(new Date()) );
			params.put("eqUserId",userOrderAccumulatesRequest.getUserId() );
			PageList<UserOrderStatistics> list = userOrderStatisticsDao.selectByMap(params, 1, 1, false);
			if(list.size() == 0){
				UserOrderStatistics orderStatistics = new UserOrderStatistics();
				orderStatistics.setMoney(new BigDecimal(userOrderAccumulatesRequest.getSumPrice()));
				orderStatistics.setUserId(userOrderAccumulatesRequest.getUserId());
				userOrderStatisticsDao.insert(orderStatistics);
			}
			else{
				UserOrderStatistics orderStatistics = list.get(0);
				orderStatistics.setMoney(new BigDecimal(userOrderAccumulatesRequest.getSumPrice()).add(orderStatistics.getMoney()));
				orderStatistics.setOrderNum(orderStatistics.getOrderNum()+1);
				userOrderStatisticsDao.update(orderStatistics);
			}
			UserLevelOrderRecord userLevelOrderRecord = new UserLevelOrderRecord();
			userLevelOrderRecord.setMoney(new BigDecimal(userOrderAccumulatesRequest.getSumPrice()));
			userLevelOrderRecord.setOrderId(userOrderAccumulatesRequest.getOrderId());
			userLevelOrderRecord.setUserId(userOrderAccumulatesRequest.getUserId());
			userLevelOrderRecord.setStatus(BackStatusEnum.NOBACK.getId());
			userLevelOrderRecordDao.insert(userLevelOrderRecord);
			response.setTip("添加成功");
			
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		return response;
	}

	/* (non-Javadoc)
	 * vip等级回滚
	 */
	@Override
	public Response levelBack(Request request) throws Exception {
		DefaultResponse response = new DefaultResponse();
		try {
			UserOrderBackRequest userOrderBackRequest = (UserOrderBackRequest) request;
			
			int userId = userOrderBackRequest.getUserId();
			String orderId = userOrderBackRequest.getOrderId();//订单号
			//1、判断订单是否存在，不存在则直接返回
			//2、判断是否已经回滚过，已回滚则直接返回
			//3、回滚user_order_statistics
			//4、判断等级
			//5、回滚等级
			Map<String,Object> params = new HashMap<String , Object>();
			params.put("eqUserId",userId );
			params.put("eqOrderId",orderId );
			PageList<UserLevelOrderRecord> list = userLevelOrderRecordDao.selectByMap(params, 1, 1, false);
			if(list.size() == 0){
				response.setTip("该订单没有登记,无需回滚");
			}else{
				UserLevelOrderRecord userLevelOrderRecord = list.get(0);
				int status = userLevelOrderRecord.getStatus();//0-未回滚，1-已回滚
				Date createDate = userLevelOrderRecord.getCreateTime();
				int year = DateUtil.getYear(createDate);
				BigDecimal money = userLevelOrderRecord.getMoney();
				if(BackStatusEnum.NOBACK.getId() ==status){
					userLevelOrderRecord.setStatus(BackStatusEnum.BACKED.getId());
					userLevelOrderRecord.setUpdateTime(new Date());
					userLevelOrderRecordDao.update(userLevelOrderRecord);//更改回滚状态
					params = new HashMap<String , Object>();
					params.put("eqOrderYear", year );
					params.put("eqUserId", userId );
					PageList<UserOrderStatistics> userOrderStatisticsList = userOrderStatisticsDao.selectByMap(params, 1, 1, false);
					if(userOrderStatisticsList.size()>0){
						UserOrderStatistics orderStatistics = userOrderStatisticsList.get(0);
						orderStatistics.setOrderNum(orderStatistics.getOrderNum()-1);
						orderStatistics.setMoney(orderStatistics.getMoney().subtract(money));
						userOrderStatisticsDao.update(orderStatistics);//回滚订单统计表
						//修改用户等级
						boolean flag = this.updateUserLevel(userId, year );
						if(flag){
							response.setTip("订单回滚成功");
						}else{
							response.setCode(ApiResultEnum.FAIL.getId());
							response.setTip("订单回滚失败");
						}
					}else{
						response.setTip("该订单已经滚回,不能再回滚");
					}
				}else{
					response.setTip("该订单已经滚回,不能再回滚");
				}
			}
			
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		return response;
	}
	
	/**
	 * 用户等级处理
	 * @param userId用户id
	 * @param year年份
	 * @return
	 */
	private boolean updateUserLevel(int userId, int year){
    	//获取今年订单总数和订单总额
    	int currentLevel = UserTypeEnum.GENERAL.getType();
    	int lastLevel = UserTypeEnum.GENERAL.getType();
    	UserOrderStatistics userOrderStatistics = getUserOrderStatistics(userId, year);
    	if(userOrderStatistics != null){
        	UserLevelUpgradeRegulation userLevelUpgradeRegulation = getUserLevelUpgradeRegulation(userOrderStatistics);
        	if(userLevelUpgradeRegulation != null){
        		currentLevel = userLevelUpgradeRegulation.getId();
        	}
    	}
    	
		UserOrderStatistics lastuserOrderStatistics = getUserOrderStatistics(userId, year-1);
		if(lastuserOrderStatistics != null){
			UserLevelUpgradeRegulation lastUserLevelUpgradeRegulation = getUserLevelUpgradeRegulation(userOrderStatistics);
			if(lastUserLevelUpgradeRegulation != null){
				lastLevel = lastUserLevelUpgradeRegulation.getId();
			}
		}
    	int level = currentLevel>lastLevel?currentLevel:lastLevel;
    	UserLevelInfo userLevelInfo = userLevelInfoDao.selectById(userId);
    	userLevelInfo.setLevelId(level);
    	userLevelInfoDao.update(userLevelInfo);
		return true;
	}
	
	/**
	 * 获取会员等级
	 * @param userOrderStatistics
	 * @return
	 */
	private UserLevelUpgradeRegulation getUserLevelUpgradeRegulation(UserOrderStatistics userOrderStatistics){
		//查询对应的会员等级规则
    	Map<String , Object> userLevelUpgradeRegulationParams = new HashMap<String , Object>();
    	userLevelUpgradeRegulationParams.put("gtOrderSumNum",userOrderStatistics.getOrderNum());
    	userLevelUpgradeRegulationParams.put("ltOrderSumNum",userOrderStatistics.getOrderNum());
    	
    	userLevelUpgradeRegulationParams.put("gtOrderSumMoney",userOrderStatistics.getMoney());
    	userLevelUpgradeRegulationParams.put("ltOrderSumMoney",userOrderStatistics.getMoney());
    	UserLevelUpgradeRegulation userLevelUpgradeRegulation = userLevelUpgradeRegulationDao.selectByData(userLevelUpgradeRegulationParams);
    	return userLevelUpgradeRegulation;
	}
	
	/**
	 * 修改会员等级，此处只考虑升级，不考虑降级修改
	 * @param userId
	 * @param levelId
	 */
	private void updateUserLevelInfo(Integer userId ,Integer levelId){
		UserLevelInfo userLevelInfo = userLevelInfoDao.selectById(userId);
		if(userLevelInfo.getLevelId() < levelId){
    		userLevelInfo.setLevelId(levelId);
    		userLevelInfoDao.update(userLevelInfo);
		}
	}
	
	/**
	 * 获取用户订单对象
	 * @param userId
	 * @param year
	 * @return
	 */
	private UserOrderStatistics getUserOrderStatistics(int userId, int year){
    	Map<String , Object> userOrderStatisticsParams = new HashMap<String , Object>();
    	userOrderStatisticsParams.put("eqUserId", userId);
    	userOrderStatisticsParams.put("eqOrderYear", year );
    	PageList<UserOrderStatistics> userOrderStatisticsList = userOrderStatisticsDao.selectByMap(userOrderStatisticsParams, 1, 1, false);
    	if(userOrderStatisticsList.size() == 0){
    		return null;
    	}else{
    		return userOrderStatisticsList.get(0);
    	}
	}

	@Override
	public Response getList(Request request) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Response getById(Request request) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Response insert(Request request) {
		// TODO Auto-generated method stub
		return null;
	}
}